package com.my.thread.simple;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.util.concurrent.*;

/**
 * 多线程
 */
@Slf4j
public class TheadTest {


    static ThreadLocal tl1 = new ThreadLocal();
    static ThreadLocal tl2 = new ThreadLocal();
    public static void main(String[] args) throws InterruptedException, ExecutionException {
//        Thread t1 = new Thread(() -> {
//            for (int i = 0; i < 10; i++) {
//                System.out.println("t1:" + i);
//                try {
//                    Thread.sleep(1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        });
        //设置为守护线程，t1在main结束后就自动结束了。不会执行休眠后的内容了
//        t1.setDaemon(true);
//        t1.start();
        //如果在main线程中调用了t1.join()，那么main线程会进入到等待状态，需要等待t1线程全部执行完毕，在恢复到就绪状态等待CPU调度。
        //阻塞主线程
//        t1.join();
        tl1.set("123");
        tl2.set("456");
        Thread t1 = new Thread(() -> {
            tl1.set("1233");
            tl2.set("4563");
            System.out.println("t1:" + tl1.get());
            System.out.println("t1:" + tl2.get());
        });
        t1.start();
        System.out.println("main:" + tl1.get());
        System.out.println("main:" + tl2.get());
        //如果ThreadLocal引用丢失，key因为弱引用会被GC回收掉，如果同时线程还没有被回收，就会导致内存泄漏，内存中的value无法被回收，同时也无法被获取到。
        //只需要在使用完毕ThreadLocal对象之后，及时的调用remove方法，移除Entry即可
        tl1.remove();
        tl2.remove();
    }
    //多线程的3种实现
    @Test
    public void test1() throws ExecutionException, InterruptedException {
        Thread t1  =new Thread(new Runnable(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("t1:" + i);
                }
            }
        });
        t1.start();

        Runnable runnable = () -> System.out.println("lambada 运行 方法级别");
        runnable.run();
        new ThreadTest().start();//1
        new Thread(new RunnableTest()).start();//2
        //3 有回调
        FutureTask futureTask = new FutureTask(new FutureTaskTest());
        new Thread(futureTask).start();
        System.out.println(futureTask.get());//获取回调信息
    }



    class ThreadTest extends Thread {

        @Override
        public void run() {
            System.out.println("11");
        }
    }

    class RunnableTest implements Runnable {
        //可以赋值进来
        String exceptionMsg;
        CountDownLatch latch;

        public RunnableTest() {

        }

        public RunnableTest(String exceptionMsg, CountDownLatch latch) {
            this.exceptionMsg = exceptionMsg;
            this.latch = latch;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "线程执行");
        }
    }

    class FutureTaskTest implements Callable<String> {
        @Override
        public String call() throws Exception {
            return "123";
        }
    }
}
